

package net.qiqbframework.commandhandling;


import net.qiqbframework.common.BuilderUtils;
import net.qiqbframework.tracing.Span;
import net.qiqbframework.tracing.SpanFactory;


public class DefaultCommandBusSpanFactory implements CommandBusSpanFactory {

    private final SpanFactory spanFactory;
    private final boolean distributedInSameTrace;


    protected DefaultCommandBusSpanFactory(Builder builder) {
        builder.validate();
        this.spanFactory = builder.builderSpanFactory;
        this.distributedInSameTrace = builder.distributedInSameTrace;
    }

    @Override
    public Span createDispatchCommandSpan(CommandMessage<?> commandMessage) {

        return spanFactory.createDispatchSpan(() -> "CommandBus.dispatchCommand", commandMessage);
    }


    @Override
    public Span createHandleCommandSpan(CommandMessage<?> commandMessage) {

        return spanFactory.createChildHandlerSpan(() -> "CommandBus.handleCommand", commandMessage);
    }

    @Override
    public <T> CommandMessage<T> propagateContext(CommandMessage<T> commandMessage) {
        return spanFactory.propagateContext(commandMessage);
    }


    public static Builder builder() {
        return new Builder();
    }


    public static class Builder {

        private SpanFactory builderSpanFactory;
        private boolean distributedInSameTrace = true;


        public Builder spanFactory(SpanFactory spanFactory) {
            BuilderUtils.assertNonNull(spanFactory, "spanFactory may not be null");
            this.builderSpanFactory = spanFactory;
            return this;
        }


        public Builder distributedInSameTrace(boolean distributedInSameTrace) {
            this.distributedInSameTrace = distributedInSameTrace;
            return this;
        }


        protected void validate() {
            BuilderUtils.assertNonNull(builderSpanFactory, "spanFactory may not be null");
        }


        public DefaultCommandBusSpanFactory build() {
            return new DefaultCommandBusSpanFactory(this);
        }
    }
}
